<template>
	<view>
		<u-navbar :autoBack="true" left-icon-color="#fff" rightIcon="setting" @rightClick="gorightClick()"
			:bgColor="bgColor" :placeholder="true">
			<view class="navtitle" slot="center">
				{{title||'聊天'}}(<text v-if="Online == true">在线</text><text v-if="Online == false">离线</text>)
			</view>
		</u-navbar>
		<view class="tips color_fff size_12" :class="{ 'show':ajax.loading }" @tap="getHistoryMsg">
			{{ajax.loadText}}
		</view>
		<view class="box-1" @click="funshow = false,cuindex=null"
			:style="funshow==true?'padding-bottom: 500rpx;':'padding-bottom: 100rpx;'">
			<view class="talk-list">
				<view v-for="(item,index) in talkList" :key="index" :id="`msg-${item.id}`">
					<view class="talk-time" v-if="item.messageType != 'RC:RcCmd'">{{ $util.timeChange(item.sentTime)}}
					</view>
					<view class="item flex_col" :class="item.type == 1 ? 'push':'pull'"
						v-if="item.messageType != 'RC:RcCmd'">
						<u--image :showLoading="true" style="border-radius: 20rpx;overflow: hidden;" :src="item.pic" loadingIcon="/static/chat/logo.png"
							errorIcon="/static/chat/logo.png" width="55px" height="55px"></u--image>
						<view style="position: relative;">
							<view class="content" v-if="item.messageType == 'RC:TxtMsg'"
								@longtap="handleLongPress(index)">{{item.content}}</view>
							<view class="content" v-if="item.messageType == 'RC:ImgMsg'"
								@longtap="handleLongPress(index)">
								<image style="width: 100px; height: 100px;" @click="goview(item.image)"
									:src="'data:image\/(jpeg|png|jpg);base64,'+item.content" mode="widthFix"></image>
							</view>
							<view v-show="cuindex == index" :class="item.type == 1 ? 'fun-data1':'fun-data2'">
								<view class="fun-item" v-if="item.messageType == 'RC:TxtMsg'"
									@tap.stop="gocory(item.content)">
									<u-icon name="order" color="#000000" size="16"></u-icon>
									<view>复制</view>
								</view>
								<view class="fun-item" v-if="item.type == 1"
									@tap.stop="gowithdraw(item.uid,item.sentTime)">
									<u-icon name="reload" color="#000000" size="16"></u-icon>
									<view>撤回</view>
								</view>
								<view class="fun-item" @tap.stop="godelete(item.uid,item.sentTime,item.type)">
									<u-icon name="trash" color="#000000" size="16"></u-icon>
									<view>删除</view>
								</view>
							</view>
						</view>
					</view>
					<view v-else class="withdraw">
						<text v-if="item.type == 1">你撤回了一条消息</text>
						<text v-else>对方撤回了一条消息</text>
					</view>
				</view>
			</view>
		</view>
		<view class="box-2">
			<view class="fun-btn">
				<view class="btn-left">
					<view class="middbox">
						<view class="midd">
							<u--input placeholder="请输入聊天内容" @input="input" color="#fff" @confirm="send" shape="circle"
								customStyle="background-color: #232526; padding: 15rpx 30rpx;" border="none"
								v-model="content"></u--input>
						</view>
					</view>
				</view>
				<view class="btn-right">
					<image src="/static/chat/fun5.png" @click="goopen(1)" mode=""></image>
					<image src="/static/chat/fun6.png" @click="goopen(2)" v-if="isshow == true" mode=""></image>
					<u-button color="#5FBC94" class="send" v-else text="发送" @click="send"></u-button>
				</view>
			</view>
			<view class="fun-box" v-show="funshow">
				<view class="emoji-div" v-show="navshow==1">
					<view class="emoji-item" v-for="(item,index) in emojiList" :key="index+'emo'"
						@click="changeEmoji(index)">
						{{item}}
					</view>
				</view>
				<view class="img-box" v-show="navshow==2">
					<view>
						<u-icon name="photo" color="#ffffff" size="50" @click="goimg('album')"></u-icon>
					</view>
					<view>
						<u-icon name="camera" color="#ffffff" size="50" @click="goimg('camera')"></u-icon>
					</view>
				</view>
			</view>
		</view>
	</view>
</template>

<script>
	import {
		emoji
	} from '@/common/emoji'
	export default {
		data() {
			return {
				bgColor: '#17191A',
				talkList: [],
				ajax: {
					rows: 20, //每页数量
					page: 1, //页码
					flag: true, // 请求开关
					loading: true, // 加载中
					time: 0,
					loadText: '正在获取消息'
				},
				emojiList: emoji,
				content: '',
				id: '',
				title: '',
				userinfo: {},
				hisinfo: {},
				funshow: false,
				isshow: true,
				navshow: 1,
				imageBase64: '',
				cuindex: null,
				expiry: 180000, // 订阅时间（单位：秒）
				Online:false
			}
		},
		onLoad(e) {
			this.id = e.id
			this.title = e.name
			this.getHistoryMsg();
			// 获取自己的信息
			this.userinfo = uni.getStorageSync('info');
			// 订阅用户
			this.subscribeToUserStatus(e.id)
			// 监听消息
			const Events = this.$RongIMLib.Events
			this.$RongIMLib.addEventListener(Events.MESSAGES, this.listener)
		},
		onShow() {
			// 获取对方信息
			this.posthisinfo()
		},
		onPageScroll(e) {
			if (e.scrollTop < 5) {
				this.getHistoryMsg();
			}
		},
		onUnload() {
			// 清除未读
			this.clearunread()
			//移除消息监听
			const Events = this.$RongIMLib.Events
			this.$RongIMLib.removeEventListener(Events.MESSAGES, this.listener)
			// 取消订阅用户userId，也是单聊的 targetId(一次最多取消订阅 200 个)
			const userIds = [this.id]
			// 取消订阅类型
			const type = this.$RongIMLib.SubscribeType.ONLINE_STATUS
			this.$RongIMLib.unSubscribeUserStatus(userIds, type).then((res) => {
				if (res.code === this.$RongIMLib.ErrorCode.SUCCESS) {
					console.log('取消订阅成功')
				} else {
					console.log('取消订阅失败', res.code, res.msg)
				}
			})

		},
		methods: {
			async subscribeToUserStatus(id) {
				try {
					const userIds = [id];
					const type = this.$RongIMLib.SubscribeType.ONLINE_STATUS; // 订阅类型：在线状态

					// 订阅用户状态
					const res = await this.$RongIMLib.subscribeUserStatus(userIds, type, this.expiry);

					if (res.code === this.$RongIMLib.ErrorCode.SUCCESS) {
						console.log('订阅成功');
						// 添加事件监听器来接收用户状态变更
						this.$RongIMLib.addEventListener(this.$RongIMLib.Events.SUBSCRIBED_USER_STATUS_CHANGE, (
							event) => {
							if (event[0].subscribeType === this.$RongIMLib.SubscribeType.ONLINE_STATUS) {
								console.log('用户状态变更', event);
								this.handleUserStatusChange(event);
							}
						});
					} else if (res.code === this.$RongIMLib.ErrorCode.RC_BESUBSCRIBED_USERIDS_COUNT_EXCEED_LIMIT) {
						console.warn('用户被订阅达到上限', res.code, res.data);
					} else {
						console.error('订阅失败', res.code, res.msg);
					}
				} catch (error) {
					console.error('订阅用户状态时发生错误', error);
				}
			},
			handleUserStatusChange(data) {
				// 处理用户状态变更的逻辑
				if (data[0].details[0].eventValue == 1) {
					this.Online = true
					// 处理用户在线逻辑
				} else {
					this.Online = false
					// 处理用户离线逻辑
				}
			},
			gorightClick() {
				uni.navigateTo({
					url: '/pages/chat/userprofile/index?id=' + this.id
				})
			},
			gowithdraw(uid, sentTime) {
				this.cuindex = null;
				const conversation = {
					targetId: this.id,
					conversationType: this.$RongIMLib.ConversationType.PRIVATE
				};
				const options = {
					messageUId: uid,
					sentTime: sentTime,
					user: {
						name: '',
						portraitUri: this.hisinfo.u_img
					}
				};
				if (this.hisinfo.berak != null) {
					options.user.name = this.hisinfo.berak
				} else {
					options.user.name = this.hisinfo.user
				}
				this.$RongIMLib.recallMessage(conversation, options).then((msg) => {
					if (msg.code == 0) {
						console.log('撤回成功！', msg);
						uni.showToast({
							title: '撤回成功！',
							icon: 'none'
						});
						let index = this.talkList.findIndex(i => i.uid == uid)
						if (index != -1) {
							this.talkList.splice(index, 1)
							this.talkList.push({
								"messageType": 'RC:RcCmd',
								"type": 1
							})
							this.$nextTick(() => {
								uni.pageScrollTo({
									scrollTop: 9999999999999, // 设置一个超大值，以保证滚动条滚动到底部
									duration: 0
								});
							})
						}

					} else {
						uni.showToast({
							title: '撤回失败！',
							icon: 'none'
						});
					}
				})
			},
			godelete(uid, sentTime, type) {
				const app = this;
				app.cuindex = null;
				uni.showModal({
					title: '提示',
					content: '是否删除此消息！',
					success: function(res) {
						if (res.confirm) {
							console.log('用户点击确定');
							const conversation = {
								targetId: app.id,
								conversationType: app.$RongIMLib.ConversationType.PRIVATE
							};
							const messages = [{
								messageUId: uid,
								sentTime: sentTime,
								messageDirection: type
							}];
							app.$RongIMLib.deleteMessages(conversation, messages).then((msg) => {
								if (msg.code == 0) {
									console.log('删除消息成功', msg);
									uni.showToast({
										title: '删除成功！',
										icon: 'none'
									});
									let index = app.talkList.findIndex(i => i.uid == uid)
									if (index != -1) {
										app.talkList.splice(index, 1)
									}
								} else {
									uni.showToast({
										title: '删除失败！',
										icon: 'none'
									});
								}
							})
						} else if (res.cancel) {
							console.log('用户点击取消');
						}
					}
				});
			},
			gocory(e) {
				let app = this
				uni.setClipboardData({
					data: e,
					success: () => {
						uni.showToast({
							title: '复制成功',
							icon: 'none'
						});
						app.cuindex = null
					},
					fail: (error) => {
						uni.showToast({
							title: '复制失败',
							icon: 'none'
						});
						app.cuindex = null
					}
				});
			},
			handleLongPress(e) {
				console.log(e)
				this.cuindex = e
			},
			goview(img) {
				let arr = []
				arr.push(img)
				uni.previewImage({
					urls: arr,
					longPressActions: {
						success: function(data) {
							console.log('选中了第' + (data.tapIndex + 1) + '个按钮,第' + (data.index + 1) + '张图片');
						},
						fail: function(err) {
							console.log(err.errMsg);
						}
					}
				});
			},
			goimg(type) {
				let app = this
				uni.chooseImage({
					count: 1,
					sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图，默认二者都有
					sourceType: [type], //从相册选择
					success: function(res) {
						console.log(res)
						console.log(JSON.stringify(res.tempFilePaths));
						//获得选择好的文件,就算只有一个文件也是数组
						const tempFilePaths = res.tempFilePaths;
						app.$util.picture(res).then(base64img => {
							console.log('压缩后的base64图片:', base64img);
							app.imageBase64 = base64img.replace(/^data:image\/(jpeg|png|jpg);base64,/,
								'');
						}).catch(err => {
							console.error('图片处理出错:', err);
						});
						uni.showLoading({
							mask: true
						})
						uni.uploadFile({
							url: '/api/upload/upload', //后端接口url
							filePath: tempFilePaths[0],
							header: {
								'Access-Control-Allow-Origin': '*',
							},
							data: {
								token: uni.getStorageSync("token") || ''
							},
							name: 'file', //和后端接口需要的参数名一致
							success: async (res1) => {
								let img = 'https://web.sunsk.top' + JSON.parse(res1.data).url;
								let info = {
									Image: img,
									base64: app.imageBase64
								};
								if (app.imageBase64.length > 10240) {
									uni.showToast({
										title: '图片质量过大,发送失败！',
										icon: 'none'
									})
									return
								} else {
									app.sendimage(info)
								}
								uni.hideLoading();
							},
							complete: (ok) => {
								uni.hideLoading()
							}
						})
					}
				});
			},
			changeEmoji(index) {
				this.content += this.emojiList[index]
			},
			goopen(num) {
				this.navshow = num
				this.funshow = true
				this.$nextTick(() => {
					uni.pageScrollTo({
						scrollTop: 9999999999999, // 设置一个超大值，以保证滚动条滚动到底部
						duration: 0
					});
				})
			},
			input(e) {
				if (e == '') {
					this.isshow = true
				} else {
					this.isshow = false
				}
			},
			clearunread() {
				const conversationType = this.$RongIMLib.ConversationType.PRIVATE;
				const targetId = this.id;
				this.$RongIMLib.clearMessagesUnreadStatus({
					conversationType,
					targetId
				}).then(res => {
					if (res.code === 0) {
						console.log(res.code)
					} else {
						console.log(res.code, res.msg)
					}
				})
			},
			listener(evt) {
				console.log('来消息啦！', evt)
				if (this.id == evt.messages[0].senderUserId) {
					if (evt.messages[0].messageType == 'RC:RcCmd') {
						let info = {
							messageType: evt.messages[0].messageType,
							type: this.id == evt.messages[0].senderUserId ? 0 : 1,
						}
						let index = this.talkList.findIndex(i => i.sentTime == evt.messages[0].content.sentTime)
						if (index != -1) {
							this.talkList.splice(index, 1)
						}
						this.ajax.loading = true;
						setTimeout(() => {
							this.hideLoadTips(true);
							this.talkList.push(info);
							this.$nextTick(() => {
								uni.pageScrollTo({
									scrollTop: 9999999999999, // 设置一个超大值，以保证滚动条滚动到底部
									duration: 0
								});
							})
						}, 300)
					} else {
						let info = {
							sentTime: evt.messages[0].sentTime,
							image: evt.messages[0].content.imageUri || '',
							messageType: evt.messages[0].messageType,
							id: evt.messages[0].messageId,
							uid: evt.messages[0].messageUId,
							content: evt.messages[0].content.content,
							type: this.id == evt.messages[0].senderUserId ? 0 : 1,
							pic: '' // 根据需要设置头像
						}
						if (this.userinfo.member_id == evt.messages[0].senderUserId) {
							info.pic = evt.messages[0].content.receivePortraitUri
						} else {
							info.pic = evt.messages[0].content.sendPortraitUri
						}
						this.ajax.loading = true;
						setTimeout(() => {
							this.hideLoadTips(true);
							this.talkList.push(info);
							this.$nextTick(() => {
								uni.pageScrollTo({
									scrollTop: 9999999999999, // 设置一个超大值，以保证滚动条滚动到底部
									duration: 0
								});
							})
						}, 300)
					}
				}
			},
			posthisinfo() {
				this.$Request({
					method: 'POST',
					url: '/api/rong/getUserInfo',
					data: {
						use_id: this.id,
					}
				}).then(res => {
					if (res.code == 1) {
						console.log(res)
						this.hisinfo = res.data
						if (this.hisinfo.berak != null && this.hisinfo.berak != '') {
							this.title = this.hisinfo.berak
						} else {
							this.title = this.hisinfo.user
						}
					}
				})
			},
			// 获取历史消息
			getHistoryMsg() {
				if (!this.ajax.flag) {
					return; //
				}
				// 此处用到 ES7 的 async/await 知识，为使代码更加优美。不懂的请自行学习。
				let get = async () => {
					this.hideLoadTips();
					this.ajax.flag = false;
					let data = await this.joinHistoryMsg();
					if (data.length < 1) {
						// 第一页，则取当前消息数据的最后一条信息元素
						this.hideLoadTips(true);
						return
					}
					if (this.ajax.page == 1) {
						this.talkList = data
					} else {
						// 将获取到的消息数据合并到消息数组中
						this.talkList = [...data, ...this.talkList];
					}

					// 数据挂载后执行，不懂的请自行阅读 Vue.js 文档对 Vue.nextTick 函数说明。
					this.$nextTick(() => {
						// 设置当前滚动的位置
						this.setPageScrollTo();
						this.hideLoadTips(true);

						if (data.length < this.ajax.rows) {
							// 当前消息数据条数小于请求要求条数时，则无更多消息，不再允许请求。
							// 可在此处编写无更多消息数据时的逻辑
						} else {
							this.ajax.page++;
							// 延迟 200ms ，以保证设置窗口滚动已完成
							setTimeout(() => {
								this.ajax.flag = true;
							}, 200)
						}

					})
				}
				get();
			},
			// 拼接历史记录消息，正式项目可替换为请求历史记录接口
			joinHistoryMsg() {
				// 此处用到 ES6 的 Promise 知识，不懂的请自行学习。
				return new Promise((done, fail) => {
					const conversation = {
						targetId: this.id,
						conversationType: this.$RongIMLib.ConversationType.PRIVATE
					};
					const option = {
						// 获取历史消息的时间戳，默认为 0，表示从当前时间获取
						timestamp: this.ajax.time,
						// 获取条数，有效值 1-100，默认为 20
						count: 20,
						// 值为 0 或 1。0 表示降序
						order: 0
					};
					if (this.ajax.page == 1) {
						option.order = 0
					} else {
						this.ajax.time = Date.now()
						option.order = 1
					}
					this.$RongIMLib.getHistoryMessages(conversation, option).then(result => {
						// 获取到的消息列表
						let data = []
						if (result.data.list.length > 0) {
							result.data.list.map((item) => {
								if (item.messageType == 'RC:RcCmd') {
									data.push({
										"sentTime": item.sentTime,
										"messageType": item.messageType,
										"type": this.id == item.senderUserId ? 0 :
										1, // 此为消息类别，设 1 为发出去的消息，0 为收到对方的消息,
									})
								} else {
									data.push({
										"sentTime": item.sentTime,
										"image": item.content.imageUri || '',
										"messageType": item.messageType,
										"id": item.messageId, // 消息的ID
										"uid": item.messageUId,
										"content": item.content.content, // 消息内容
										"type": this.id == item.senderUserId ? 0 :
										1, // 此为消息类别，设 1 为发出去的消息，0 为收到对方的消息,
										"pic": this.id == item.senderUserId ? item.content
											.receivePortraitUri : item.content
											.sendPortraitUri // 头像
									})
								}
							})
						}
						this.ajax.flag = result.data.hasMore; // 是否还有历史消息可获取
						done(data);
						console.log('获取历史消息成功', result.data.list, result.data.hasMore);
					}).catch(error => {
						console.log('获取历史消息失败', error);
						this.ajax.flag = false
						this.ajax.loading = false
						uni.showToast({
							title: '连接失败！',
							icon: 'none'
						})
					});
				})
			},
			// 设置页面滚动位置
			setPageScrollTo() {
				setTimeout(() => {
					uni.pageScrollTo({
						scrollTop: 9999999999999, // 设置一个超大值，以保证滚动条滚动到底部
						duration: 0
					});
				}, 300)
			},
			// 隐藏加载提示
			hideLoadTips(flag) {
				if (flag) {
					this.ajax.loadText = '消息获取成功';
					setTimeout(() => {
						this.ajax.loading = false;
					}, 300);
				} else {
					this.ajax.loading = true;
					this.ajax.loadText = '正在获取消息';
				}
			},
			sendimage(info) {
				// 定义消息投送目标会话
				const conversation = {
					conversationType: this.$RongIMLib.ConversationType.PRIVATE,
					targetId: this.id
				}
				// 实例化待发送消息，RongIMLib.TextMessage 为内置文本型消息
				const message = new this.$RongIMLib.ImageMessage({
					// 文本内容
					messageType: 'RC:ImgMsg',
					content: info.base64,
					image: info.Image,
					receiveName: this.hisinfo.berak || this.hisinfo.user,
					receivePortraitUri: this.hisinfo.u_img,
					sendName: this.userinfo.user,
					sendPortraitUri: 'https://web.sunsk.top/' + this.userinfo.u_img
				})
				// 配置属性
				const options = {
					// 如果需要发送 @ 消息，isMentioned 需设置为 true
					isMentioned: false,
				}
				// 发送消息
				this.$RongIMLib.sendMessage(conversation, message, options).then(res => {
					if (res.code === this.$RongIMLib.ErrorCode.SUCCESS) {
						// 消息发送成功，可以根据返回结果中的 messageId 字段将列表中的该消息状态改为发送成功。
						console.log('消息发送成功', res.data)
						this.talkList.push({
							sentTime: res.data.sentTime,
							messageType: 'RC:ImgMsg',
							imageUri: info.Image,
							id: res.data.messageId,
							uid: res.data.messageUId,
							content: res.data.content.content,
							type: 1, // 发出去的消息类型
							pic: 'https://web.sunsk.top/' + this.userinfo.u_img // 根据需要设置头像
						});
						this.$nextTick(() => {
							uni.pageScrollTo({
								scrollTop: 9999999999999, // 设置一个超大值，以保证滚动条滚动到底部
								duration: 0
							});
						})
					} else {
						console.log('消息发送失败', res.code, res.msg)
						uni.showToast({
							title: '消息发送失败！',
							icon: 'none'
						})
					}
				})
			},
			// 发送信息
			send() {
				if (!this.content) {
					uni.showToast({
						title: '请输入有效的内容',
						icon: 'none'
					})
					return;
				}
				// 定义消息投送目标会话
				const conversation = {
					conversationType: this.$RongIMLib.ConversationType.PRIVATE,
					targetId: this.id
				}
				// 实例化待发送消息，RongIMLib.TextMessage 为内置文本型消息
				const message = new this.$RongIMLib.TextMessage({
					// 文本内容
					messageType: 'RC:TxtMsg',
					content: this.content,
					receiveName: this.hisinfo.berak || this.hisinfo.user,
					receivePortraitUri: this.hisinfo.u_img,
					sendName: this.userinfo.user,
					sendPortraitUri: 'https://web.sunsk.top/' + this.userinfo.u_img

				})
				// 配置属性
				const options = {
					// 如果需要发送 @ 消息，isMentioned 需设置为 true
					isMentioned: false,
				}
				// 发送消息
				this.$RongIMLib.sendMessage(conversation, message, options).then(res => {
					if (res.code === this.$RongIMLib.ErrorCode.SUCCESS) {
						// 消息发送成功，可以根据返回结果中的 messageId 字段将列表中的该消息状态改为发送成功。
						console.log('消息发送成功', res.data)
						this.talkList.push({
							sentTime: res.data.sentTime,
							messageType: 'RC:TxtMsg',
							id: res.data.messageId,
							uid: res.data.messageUId,
							content: res.data.content.content,
							type: 1, // 发出去的消息类型
							pic: 'https://web.sunsk.top/' + this.userinfo.u_img // 根据需要设置头像
						});
						this.$nextTick(() => {
							// 清空内容框中的内容
							this.content = '';
							this.isshow = true
							uni.pageScrollTo({
								scrollTop: 9999999999999, // 设置一个超大值，以保证滚动条滚动到底部
								duration: 0
							});
						})
					} else {
						console.log('消息发送失败', res.code, res.msg)
						uni.showToast({
							title: '消息发送失败！',
							icon: 'none'
						})
					}
				})
			}
		}
	}
</script>
<style lang="scss">
	/* 根元素样式 设置页面背景、字体大小、字体颜色，字符间距、长单词换行 */
	page {
		background-color: #17191A;
		font-size: 28rpx;
		box-sizing: border-box;
		color: #333;
		letter-spacing: 0;
		word-wrap: break-word;
	}

	/* 设置常用元素尺寸规则 */
	view,
	textarea,
	input,
	label,
	form,
	button,
	image {
		box-sizing: border-box;
	}

	/* 按钮样式处理 */
	button {
		font-size: 28rpx;
	}

	/* 取消按钮默认的边框线效果 */
	button:after {
		border: none;
	}

	/* 设置图片默认样式，取消默认尺寸 */
	image {
		display: block;
		height: auto;
		width: auto;
	}

	/* 输入框默认字体大小 */
	textarea,
	input {
		font-size: 28rpx;
	}
</style>
<style lang="scss" scoped>
	.navtitle {
		color: #fff;
	}

	.flex_col {
		display: flex;
		flex-direction: row;
		flex-wrap: nowrap;
		justify-content: flex-start;
		align-items: center;
		align-content: center;
	}

	.color_fff {
		color: #fff;
	}

	.size_12 {
		font-size: 24rpx;
	}

	/* 遮罩 */
	.shade {
		position: fixed;
		top: 0;
		right: 0;
		bottom: 0;
		left: 0;
		background-color: rgba(0, 0, 0, 0.8);
		z-index: 100;
	}

	/* 弹窗 */
	.shade_box {
		position: fixed;
		top: 0;
		right: 0;
		bottom: 0;
		left: 0;
		margin: auto;
		z-index: 101;
		min-width: 200rpx;
		min-height: 200rpx;
	}

	/* 加载数据提示 */
	.tips {
		position: fixed;
		left: 0;
		top: 88rpx;
		width: 100%;
		z-index: 9;
		background-color: rgba(0, 0, 0, 0.15);
		height: 72rpx;
		line-height: 72rpx;
		transform: translateY(-80rpx);
		transition: transform 0.3s ease-in-out 0s;
		text-align: center;

		&.show {
			transform: translateY(0);
		}
	}

	.box-1 {
		width: 100%;
		height: auto;
		box-sizing: content-box;
		/* 兼容iPhoneX */
		margin-bottom: 0;
		margin-bottom: constant(safe-area-inset-bottom);
		margin-bottom: env(safe-area-inset-bottom);
	}

	.voice-bar {
		width: 300rpx;
		height: 200rpx;
		background-color: #5FBC94;
		position: fixed;
		left: 0;
		right: 0;
		top: 33%;
		margin: auto;
		z-index: 99;
		border-radius: 20rpx;
		display: flex;
		align-items: center;
		justify-content: center;

		.time {
			margin-left: 10rpx;
		}
	}

	.box-2 {
		position: fixed;
		left: 0;
		width: 100%;
		bottom: 0;
		height: auto;
		z-index: 99;
		box-sizing: content-box;
		background-color: #1D2123;
		/* 兼容iPhoneX */
		padding-bottom: 0;
		padding-bottom: constant(safe-area-inset-bottom);
		padding-bottom: env(safe-area-inset-bottom);

		.img-box {
			height: 400rpx;
			padding: 30rpx;
			border-top: 2px solid #dedede;
			display: flex;

			view {
				margin-right: 20rpx;
			}
		}

		.emoji-div {
			height: 400rpx;
			padding: 20rpx;
			border-top: 2px solid #dedede;
			flex-wrap: wrap;
			overflow-y: scroll;
			display: flex;
			align-items: center;

			.emoji-item {
				width: 12.5%;
				height: 40rpx;
				margin-bottom: 20px;
				font-size: 50rpx;
				text-align: center;
			}
		}

		.fun-btn {
			width: 100%;
			display: flex;
			align-items: center;
			padding: 20rpx 30rpx;
			justify-content: space-between;

			.btn-right {
				display: flex;
				align-items: center;
				justify-content: space-between;

				image {
					width: 42.03rpx;
					height: 42.03rpx;
					margin-left: 20rpx;
				}

				.send {
					margin-left: 20rpx;
					color: #fff;
					height: 54rpx;
					width: 100rpx;
					line-height: 54rpx;
				}
			}

			.btn-left {
				width: 100%;
				display: flex;
				align-items: center;

				.middbox {
					width: 100%;

					.midd {}
				}
			}
		}
	}

	.talk-list {
		padding-bottom: 20rpx;

		.talk-time {
			text-align: center;
			color: #fff;
			padding: 30rpx 0 10rpx 0;
			font-size: 24rpx;
		}

		.withdraw {
			text-align: center;
			color: #fff;
			font-size: 24rpx;
			padding: 30rpx 0;
		}

		/* 消息项，基础类 */
		.item {
			padding: 20rpx 20rpx 0 20rpx;
			align-items: flex-start;
			align-content: flex-start;
			color: #333;

			.fun-data1 {
				position: absolute;
				top: -80rpx;
				right: 30rpx;
				background-color: #fff;
				padding: 0 10rpx;
				display: flex;
				border-radius: 10rpx;
				align-items: center;
				justify-content: space-between;
				z-index: 9;

				.fun-item {
					width: 100rpx;
					padding: 20rpx 0;
					justify-content: center;
					display: flex;
					align-items: center;
					font-size: 26rpx;
				}

				&::after {
					content: '';
					display: block;
					width: 0;
					height: 0;
					border-top: 16rpx solid transparent;
					border-bottom: 16rpx solid transparent;
					border-right: 20rpx solid #fff;
					position: absolute;
					bottom: -18rpx;
					z-index: -1;
					/* 调整箭头位置，向上偏移 */
					right: 10rpx;
					/* 调整箭头位置，向左偏移 */
					transform: rotate(-90deg);
					/* 将箭头旋转45度，使其朝向右下角 */
				}
			}

			.fun-data2 {
				position: absolute;
				top: -80rpx;
				left: 30rpx;
				background-color: #fff;
				padding: 0 10rpx;
				display: flex;
				border-radius: 10rpx;
				align-items: center;
				justify-content: space-between;
				z-index: 9;

				.fun-item {
					width: 100rpx;
					padding: 20rpx 0;
					display: flex;
					align-items: center;
					justify-content: center;
					font-size: 24rpx;
				}

				&::after {
					content: '';
					display: block;
					width: 0;
					height: 0;
					border-top: 16rpx solid transparent;
					border-bottom: 16rpx solid transparent;
					border-left: 20rpx solid #fff;
					/* 使用 border-left 替换 border-right */
					position: absolute;
					bottom: -18rpx;
					left: 10rpx;
					z-index: -1;
					/* 调整箭头位置，向左偏移 */
					transform: rotate(90deg);
					/* 将箭头旋转为垂直向上 */
				}
			}

			.pic {
				width: 92rpx;
				height: 92rpx;
				border-radius: 50%;
				border: #fff solid 1px;
			}

			.content {
				padding: 20rpx;
				border-radius: 4px;
				max-width: 500rpx;
				word-break: break-all;
				line-height: 52rpx;
				position: relative;
			}

			/* 收到的消息 */
			&.pull {
				.content {
					margin-left: 32rpx;
					background-color: #dddddd;

					&::after {
						content: '';
						display: block;
						width: 0;
						height: 0;
						border-top: 16rpx solid transparent;
						border-bottom: 16rpx solid transparent;
						border-right: 20rpx solid #dddddd;
						position: absolute;
						top: 30rpx;
						left: -18rpx;
					}
				}
			}

			/* 发出的消息 */
			&.push {
				/* 主轴为水平方向，起点在右端。使不修改DOM结构，也能改变元素排列顺序 */
				flex-direction: row-reverse;

				.content {
					margin-right: 32rpx;
					background-color: #a0e959;

					&::after {
						content: '';
						display: block;
						width: 0;
						height: 0;
						border-top: 16rpx solid transparent;
						border-bottom: 16rpx solid transparent;
						border-left: 20rpx solid #a0e959;
						position: absolute;
						top: 30rpx;
						right: -18rpx;
					}
				}
			}
		}
	}
</style>